<script setup lang="ts">
import type { AgentBaseInfo } from "@/common/apis/intelligent/type"
import type { UploadType } from "@@/constants/other-keys"
import type { FormInstance, FormRules, UploadUserFile } from "element-plus"
import { createAgentDataApi, getAgentInfoApi, getAgentTypeOptionsApi, updateAgentDataApi } from "@/common/apis/intelligent"
import { getProjectId } from "@/common/utils/cache/local-storage"
import UploadFolder from "@@/components/UploadFolder/index.vue"
import { agentSupportSide, agentSupportSideMap, FormTypeEnum } from "@@/constants/other-keys"
import { filesToZip } from "@@/utils/fileUtils"
import { ElMessage, ElMessageBox } from "element-plus"
import { cloneDeep, isEqual } from "lodash-es"
import { computed, ref, watch } from "vue"
import { isEmpty } from "xe-utils"

interface Props {
  id: string | undefined
  dialogType: FormTypeEnum
  visible: boolean
}

const props = withDefaults(defineProps<Props>(), {
  dialogType: FormTypeEnum.VIEW
})
const emit = defineEmits(["closeDialog"])
const DEFAULT_FORM_DATA: AgentBaseInfo = {
  agent_id: undefined,
  agent_name: "",
  agent_code: "",
  agent_type: "",
  agent_path: "",
  main_file: "",
  agent_support_side: "3",
  agent_describe: "",
  agent_image_id: ""
}
const dialogVisible = ref<boolean>(false)
const formRef = ref<FormInstance | null>(null)
const formData = ref<AgentBaseInfo>(cloneDeep(DEFAULT_FORM_DATA))
const formRules: FormRules<AgentBaseInfo> = {
  agent_name: [{ required: true, trigger: "blur", message: "请输入智能体名称" }],
  agent_code: [{ required: true, trigger: "blur", message: "请输入智能体类名" }],
  agent_type: [{ required: true, trigger: "change", message: "请选择智能体类型" }],
  agent_path: [{ required: true, trigger: "change", message: "请选择文件" }],
  main_file: [{ required: true, trigger: "change", message: "请输入主文件名称" }],
  agent_support_side: [{ required: true, trigger: "change", message: "请选择支持阵营" }]
}
const fileList = ref<UploadUserFile[]>([])
const loading = ref<boolean>(false)
const detailLoading = ref<boolean>(false)
const uploadType = ref<UploadType>()
const isEdit = ref<boolean>(false)
const defaultFormData = ref<AgentBaseInfo>(cloneDeep(DEFAULT_FORM_DATA))
const agentTypeOptions = ref<string[]>([])

const textMap = computed(() => {
  if (props.dialogType === FormTypeEnum.CREATE) return "上传智能体"
  else if (props.dialogType === FormTypeEnum.EDIT) return "编辑智能体"
  else return "查看智能体"
})
function getAgentInfo() {
  detailLoading.value = true
  props.id
  && getAgentInfoApi(props.id)
    .then(({ data }) => {
      if (data) {
        formData.value = cloneDeep(data)
        formData.value.agent_path = data.agent_files_path
        formData.value.agent_support_side = `${data.agent_support_side}`
      } else {
        ElMessage("数据不存在")
      }
    })
    .finally(() => {
      detailLoading.value = false
    })
}
function showDialog() {
  formRef.value?.resetFields()
  fileList.value = []
  isEdit.value = false
  detailLoading.value = false
  if (props.dialogType !== FormTypeEnum.CREATE) {
    getAgentInfo()
  }
}
function closeDialog() {
  formRef.value?.resetFields()
  emit("closeDialog", undefined)
}
async function getParam(): Promise<FormData> {
  // eslint-disable-next-line no-async-promise-executor
  return new Promise(async (resolve) => {
    const params = new FormData()
    if (props.dialogType !== FormTypeEnum.CREATE && props.id) {
      params.append("agent_id", props.id)
    }
    if (!isEmpty(getProjectId()))
      params.append("project_id", getProjectId())
    params.append("agent_name", formData.value.agent_name)
    params.append("agent_code", formData.value.agent_code)
    params.append("describe", formData.value.agent_describe)
    params.append("agent_type", formData.value.agent_type)
    params.append("main_file", formData.value.main_file)
    params.append(`agent_support_side`, formData.value.agent_support_side)
    if (uploadType.value !== undefined && fileList.value.length > 0) {
      if (uploadType.value === "Folder") {
        // 压缩zip
        const files = fileList.value as File[]
        const fileBlob = await filesToZip(files)
        params.append("agent_files", fileBlob, `${formData.value.agent_path}.zip`)
      }
      if (uploadType.value === "File") {
        const files = fileList.value as UploadUserFile[]
        params.append("agent_files", files[0].raw as Blob)
      }
    }
    resolve(params)
  })
}
function handleConfirm() {
  formRef.value?.validate(async (valid: boolean, fields) => {

    if (!valid) return console.error("表单校验不通过", fields)

    loading.value = true
    const api = props.dialogType == FormTypeEnum.CREATE ? createAgentDataApi : updateAgentDataApi
    const params: FormData = await getParam()
    api(params)
      .then(() => {
        ElMessage.success("操作成功")
        emit("closeDialog", "refresh")
      })
      .finally(() => {
        loading.value = false
      })
  })
}
function handleCloseTip(done: () => void) {
  if (props.dialogType === FormTypeEnum.VIEW && !isEdit.value) {
    closeDialog()
    done()
    return
  }
  // 校验值是否相同
  if (isEqual(defaultFormData.value, formData.value)) {
    closeDialog()
    done()
    return
  }
  ElMessageBox.confirm("当前编辑未保存，是否确定关闭？").then(() => {
    done()
  })
}
function handleEdit() {
  defaultFormData.value = cloneDeep(formData.value)
  isEdit.value = true
}
function handleEditCancel() {
  isEdit.value = false
  getAgentInfo()
}
function handleEditSave() {
  formRef.value?.validate(async (valid: boolean, fields) => {
    if (!valid) return console.error("表单校验不通过", fields)
    loading.value = true
    const params: FormData = await getParam()
    updateAgentDataApi(params)
      .then(() => {
        ElMessage.success("操作成功")
        isEdit.value = false
      })
      .finally(() => {
        loading.value = false
      })
  })
}

watch(
  () => [props.id, props.dialogType, props.visible],
  () => {
    dialogVisible.value = props.visible
    if (props.visible) {
      showDialog()
    }
  }
)
watch(
  () => [props.id, props.dialogType],
  () => {
    fileList.value = []
    formData.value = cloneDeep(DEFAULT_FORM_DATA)
    defaultFormData.value = cloneDeep(formData.value)
    if (props.dialogType !== FormTypeEnum.CREATE) {
      getAgentInfo()
    }
  }
)
watch(
  () => fileList.value,
  () => {
    if (fileList.value.length > 0) {
      formData.value.agent_path = fileList.value[0].name
    }
  }
)
watch(
  () => fileList.value,
  () => {
    if (uploadType.value != undefined && fileList.value.length > 0) {
      if (uploadType.value == "File") {
        const files = fileList.value as UploadUserFile[]
        formData.value.agent_path = files[0].name
      }
      if (uploadType.value == "Folder") {
        // 文件夹
        const files = fileList.value as File[]
        const relativePath = files[0].webkitRelativePath
        const folderName = relativePath && relativePath.split("/")[0]
        formData.value.agent_path = folderName
      }
    } else {
      formData.value.agent_path = ""
    }
  },
  { deep: true }
)

onMounted(() => {
  getAgentTypeOptionsApi().then(({ data }) => {
    agentTypeOptions.value = data.type
  })
})
</script>

<template>
  <el-drawer
    v-model="dialogVisible"
    direction="rtl"
    size="600px"
    @close-auto-focus="closeDialog"
    @close="closeDialog"
    :before-close="handleCloseTip"
    :show-close="false"
    :append-to-body="true"
  >
    <template #header>
      <div class="drawer-header">
        <h4>{{ textMap }}</h4>
        <el-space>
          <el-button v-if="isEdit" v-throttle="() => handleEditCancel()">
            取消保存
          </el-button>
          <el-button v-if="isEdit" type="primary" v-throttle="() => handleEditSave()">
            保存
          </el-button>
          <el-button v-if="!isEdit && props.dialogType == FormTypeEnum.VIEW" type="primary" v-throttle="() => handleEdit()">
            编辑
          </el-button>
        </el-space>
      </div>
    </template>
    <template #default>
      <el-form
        v-if="dialogType != FormTypeEnum.VIEW || isEdit"
        ref="formRef"
        :model="formData"
        :rules="formRules"
        width="600"
        label-width="120px"
        label-position="right"
        :close-on-click-modal="false"
        v-loading="detailLoading"
      >
        <el-form-item label="智能体名称" prop="agent_name">
          <el-input v-model="formData.agent_name" autocomplete="off" placeholder="请输入" />
        </el-form-item>
        <el-form-item label="智能体类名" prop="agent_code">
          <el-input v-model="formData.agent_code" autocomplete="off" placeholder="请输入" />
        </el-form-item>
        <el-form-item label="智能体类型" prop="agent_type">
          <el-select
            v-model="formData.agent_type"
            clearable
            placeholder="请选择"
            popper-class="drawer-select-popper"
          >
            <el-option
              v-for="item in agentTypeOptions"
              :key="item"
              :label="item"
              :value="item"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="支持阵营" prop="agent_support_side">
          <el-select
            v-model="formData.agent_support_side"
            clearable
            placeholder="请选择"
            popper-class="drawer-select-popper"
          >
            <el-option
              v-for="item in agentSupportSide"
              :key="item.value"
              :label="item.name"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="智能体文件" prop="agent_path">
          <UploadFolder
            accept=".zip"
            :file-name="formData.agent_path"
            v-model:upload-type="uploadType"
            v-model:upload-files="fileList"
          />
        </el-form-item>
        <el-form-item label="主文件" prop="main_file">
          <el-input
            v-model="formData.main_file"
            placeholder="请输入主文件名称"
          />
        </el-form-item>
        <el-form-item label="智能体描述" prop="agent_describe">
          <el-input
            v-model="formData.agent_describe"
            :rows="3"
            type="textarea"
            :placeholder="`${props.dialogType == FormTypeEnum.VIEW && !isEdit ? '' : '可以输入智能体的基本逻辑，应用场景等信息，最多输入600字'}`"
            maxlength="600"
          />
        </el-form-item>
      </el-form>

      <el-form
        v-else
        width="600"
        label-width="120px"
        label-position="right"
        :close-on-click-modal="false"
        v-loading="detailLoading"
        class="custom-view-form"
      >
        <el-form-item label="智能体名称：">
          {{ $getViewText(formData.agent_name) }}
        </el-form-item>
        <el-form-item label="智能体类型：">
          {{ $getViewText(formData.agent_type) }}
        </el-form-item>
        <el-form-item label="支持阵营：">
          {{ $getViewText(agentSupportSideMap[formData.agent_support_side]) }}
        </el-form-item>
          <el-form-item label="智能体文件：">
            {{ $getViewText(formData.agent_path) }}
          </el-form-item>
        <el-form-item label="智能体描述：">
          {{ $getViewText(formData.agent_describe) }}
        </el-form-item>
      </el-form>
    </template>
    <template v-if="dialogType !== FormTypeEnum.VIEW" #footer>
      <div class="dialog-footer">
        <el-button plain v-throttle="() => closeDialog()">
          取 消
        </el-button>
        <el-button :loading="loading" type="primary" v-throttle="() => handleConfirm()">
          确 定
        </el-button>
      </div>
    </template>
    <template v-else #footer>
      <div class="dialog-footer">
        <el-button plain v-throttle="() => closeDialog()">
          关 闭
        </el-button>
      </div>
    </template>
  </el-drawer>
</template>

<style lang="scss" scoped>
.upload-demo {
  width: 100% !important;
}
:deep(.el-upload.el-upload--text) {
  width: 100% !important;
}
</style>
